package com.lxm.oauth2server.config;

import com.lxm.oauth2server.config.service.MyUserdDetailsService;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

import javax.annotation.Resource;

/**
 * @ClassName: AuthoricationServerConfig oauth2的认证中心配置
 * @Description:
 *               创建一个配置类继承AuthorizationServerConfigurerAdapter
 *               加上@Configuration注解 使其成为一个配置类
 *               加上@EnableAuthorizationServer注解 使其作为认证中心
 * @author: liangxingming
 * @date: 2020年05月07日 9:49
 */
@Configuration
@EnableAuthorizationServer
public class AuthoricationServerConfig extends AuthorizationServerConfigurerAdapter {

    // 4、注入AuthenticationManager
    @Resource
    private AuthenticationManager authenticationManager;

    // 8、注入MyUserdDetailsService
    @Resource
    private MyUserdDetailsService myUserdDetailsService;

    /**
     * 重写客户端相关配置
     * 1、配置客户端（应用）信息 非用户信息
     * 客户端详细信息在这里进行初始化，你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //super.configure(clients);
        // 在内存中存储客户端信息
        clients.inMemory()
                // 配置客户端Id
                .withClient("client")
                //客户端密钥 “{}”为加密方式 noop为不加密
                //现如今Spring Security中密钥的存储格式是“{id}…………” 所以“{}”必要 否则报错：There is no PasswordEncoder mapped for the id “null” 详情移步官方文档
                .secret("{noop}123456")
                // 配置授权范围 read、write、all
                .scopes("all")
                // 配置该客户端支持的授权方式
                .authorizedGrantTypes("authorization_code","password","client_credentials","refresh_token","implicit")
                // token令牌有效期 单位s
                .accessTokenValiditySeconds(1800)
                // refreshtoken刷新令牌有效期 单位s 一般来说刷新令牌比令牌有效期长 便于使用刷新令牌换取令牌
                .refreshTokenValiditySeconds(3600)
                // 6、指定重定向地址 授权码认证模式和简化认证模式中必须
                .redirectUris("http://www.baidu.com");
                // 基本上来说 到这一步就完成了一个客户端的配置了
                // 如果想要配置多个客户端 往下使用.and()连接
                //.and().withClient().secret().scopes().authorizedGrantTypes().accessTokenValiditySeconds().refreshTokenValiditySeconds();
    }

    /**
     * 配置授权服务器端点的属性和增强的功能。
     * 定义授权和令牌端点以及令牌服务
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        //super.configure(endpoints);
        endpoints.authenticationManager(authenticationManager); //5、将authenticationManager交给服务器端点
        endpoints.userDetailsService(myUserdDetailsService); // 9、将myUserdDetailsService交给服务器端点
    }

    /**
     * 定义令牌端点上的安全约束
     * @param security
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        super.configure(security);
    }
}
